﻿using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Extensions.DependencyInjection;
using RQX.Common.Web.Tools;
using RQX.Common.Web.Web.Startup;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Loader;

namespace RQX.Common.Web.Web.Plug
{
    public static class PlugControllerExtension
    {
        public static void PlugMvcControllerBuilder(this IMvcBuilder mvcBuilder, IServiceCollection services)
        {
            //var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            //FileSystemWatcher watcher = new FileSystemWatcher(path, "*.dll");
            //watcher.EnableRaisingEvents = true;
            //watcher.Changed += (object sender, FileSystemEventArgs e) =>
            //{
            //    PlugDirChanging(sender, e, mvcBuilder, services);
            //};

            PlugDirChanging(null, null, mvcBuilder, services);
        }
        /// <summary>
        /// 插件目录更新，热插拔
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="mvcBuilder"></param>
        /// <param name="services"></param>
        private static void PlugDirChanging(object sender, FileSystemEventArgs e, IMvcBuilder mvcBuilder, IServiceCollection services)
        {
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            var partManager = services.GetSingletonInstanceOrNull<ApplicationPartManager>();

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            var pathFiles = Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories);

            for (int i = 0; i < pathFiles.Length; i++)
            {
                FileInfo fileInfo = new FileInfo(pathFiles[i]);
                //try
                //{
                using var fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read);
                var assembly = new AssemblyLoadContext(Guid.NewGuid().ToString("N"), true).LoadFromStream(fs);
                var list = partManager.ApplicationParts.Where(k => k.Name.Equals(fileInfo.Name.Left(fileInfo.Name.Length - 4)));
                if (list.Count() > 0)
                {
                    list.ToList().ForEach(item => partManager.ApplicationParts.Remove(item));
                    //var removeFeature = partManager.FeatureProviders.Where(k => k.GetType() == typeof(DynamicApiControllerFeatureProvider));
                    //removeFeature.ToList().ForEach(feature => partManager.FeatureProviders.Remove(feature));
                }
                mvcBuilder.AddApplicationPart(assembly);
                //}
                //catch(Exception ex)
                //{
                //    int a=1;
                //}
            }
            //services.AddDynamicApiService();
        }
    }
}
